import org.apache.commons.io.FileUtils
import java.io.File
import java.io.FileInputStream
import java.nio.charset.Charset
import java.util.*

data class SystemCfg(val base: String, val gitrepobase: String,
                     val gitRepoCfg: Map<String, List<GitRepoCfg>>)

data class GitRepoCfg(
    val token: String,
    val repo: String,
    val username: String,
    val password: String,
)


/**
 * 远程同步仓库配置
 * */
fun loadGitRepoCfg(fp: String = "./git-repo.ini"): Map<String, List<GitRepoCfg>> {
    return FileUtils.readLines(File(fp), "utf-8")
        .filter { it.isNotEmpty() }
        .map {
            val cfg = it.split(",")
            GitRepoCfg(cfg[0], cfg[1], cfg[2], cfg[3])
        }.groupBy { it.token }
}

data class NotifyCtx(val base: String)

fun loadNotifyCfg(fp: String = "./notify.ini"): NotifyCtx {
    println(File(fp).absolutePath)
    val props = Properties()
    FileInputStream(fp).use {
        props.load(it)
    }
    return NotifyCtx(props.getProperty("notify.base", ".jnotify"))
}

var SYSTEM_CONFG: SystemCfg = loadSystemConfig()

fun loadSystemConfig(): SystemCfg {
    val base = loadNotifyCfg().base
    val gitrepobase = base + File.separator + "gitrepos"
    val gitRepoCfg = loadGitRepoCfg()
    return SystemCfg(base, gitrepobase, gitRepoCfg)
}

data class ListenerCtx(val basefp: String, val listenerDir: String)

fun getListenerCtx(repoToken: String): ListenerCtx {
    val basefp = SYSTEM_CONFG.gitrepobase + File.separator + repoToken
    return ListenerCtx(basefp, basefp + File.separator + "listener.ini")
}

fun appendListenerDir(repoToken: String, listenerdir: String) {
    if (SYSTEM_CONFG.gitRepoCfg[repoToken] == null) {
        throw IllegalArgumentException("未找到对应仓库")
    }
    val listenerCtx = getListenerCtx(repoToken)
    val dirToken = System.currentTimeMillis()
    println(listenerCtx.toString())
    if (!File(listenerCtx.listenerDir).exists()) {
        FileUtils.touch(File(listenerCtx.listenerDir))
        FileUtils.writeStringToFile(File(listenerCtx.listenerDir), "$dirToken,$listenerdir\n", Charset.forName("utf-8"))
        FileUtils.forceMkdir(File(listenerCtx.basefp + File.separator + dirToken))
    } else {
        var isRepeat = false
        FileUtils.readLines(File(listenerCtx.listenerDir), "utf-8")
            .filter { it.isNotBlank() }
            .forEach {
                val split = it.split(",")
                println("${split[0]} ${split[1]}")
                if (split[1] == listenerdir) {
                    isRepeat = true
                }
            }
        if (isRepeat ) {
            throw IllegalArgumentException("$listenerdir 正在被监控,无法被重复监视")
        }
        println("$dirToken,$listenerdir\n")
        FileUtils.writeStringToFile(
            File(listenerCtx.listenerDir),
            "$dirToken,$listenerdir\n",
           "utf-8",true)
    }
}

/**
 * 只删除监控配置，文件这里不删
 * */
fun removeListenerDir(repoToken: String, listenerDir: String) {
    if (SYSTEM_CONFG.gitRepoCfg[repoToken] == null) {
        return
    }
    val listenerCtx = getListenerCtx(repoToken)
    if (!File(listenerCtx.listenerDir).exists()) {
        return
    }
    val lds = FileUtils.readLines(File(listenerCtx.listenerDir), "utf-8").filter {
        it.isNotBlank()
    }.filter {
        it.split(",")[1] != listenerDir
    }.toList()
    FileUtils.writeLines(File(listenerCtx.listenerDir), lds)
}

/**
 * 删除所有位置的监控文件
 * */
fun removeListenerDir(listenerDir: String) {
    SYSTEM_CONFG.gitRepoCfg.keys.forEach {
        removeListenerDir(it, listenerDir)
    }
}

fun initPj() {
    FileUtils.forceMkdir(File(SYSTEM_CONFG.base))
    FileUtils.forceMkdir(File(SYSTEM_CONFG.gitrepobase))
    SYSTEM_CONFG.gitRepoCfg.forEach {
        FileUtils.forceMkdir(File(SYSTEM_CONFG.gitrepobase, it.key))
    }
}
/**
 * base
 *  - gitrepo
 *     - repotoken
 *       - syncdir
 *  -
 * */
/**
 * 初始化安装目录工程
 * */
fun install() {
    initPj()
}

fun cleanDirtyDir() {
    val gitrepobase = SYSTEM_CONFG.gitrepobase
    println(gitrepobase)
    File(gitrepobase).listFiles()?.filter { it.isDirectory }?.forEach { gitrepo ->
        val validDirs = FileUtils.readLines(File(gitrepo.absolutePath, "listener.ini"), "utf-8")
            .filter { it.isNotBlank() }.map { it.split(",")[0] }.toList()
        gitrepo.listFiles()?.filter { it.isDirectory }?.forEach {
            if (!validDirs.contains(it.name)) {
                FileUtils.deleteDirectory(it)
            }
        }
    }
}

